package com.els.search.service.imlp;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.els.search.entity.FakeNews;
import com.els.search.mapper.FakeNewsMapper;
import com.els.search.service.FakeNewsService;
import com.els.search.service.TestFakeNewsService;
import com.els.search.utils.ESconst;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.common.xcontent.json.JsonXContent;
import org.elasticsearch.index.query.MatchAllQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * @title: FakeNewsServiceImpl
 * @projectName fake-baidu
 * @Date: 2021/7/12 12:43
 * @Author: lei.yu-esint
 * @Description:
 */
@Service
public class TestFakeNewsServiceImpl implements TestFakeNewsService {

    @Autowired(required = false)
    private FakeNewsMapper fakeNewsMapper;

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    @Override
    public IPage<FakeNews> selectData(String keyword,String page,String size) {

        //初始化页码
        Long pageN=Long.valueOf(page);
        Long sizeN=Long.valueOf(size);

        //分页构造
        IPage<FakeNews> pageParam = new Page<>(pageN, sizeN);

        //条件构造
        Wrapper wrapper=new QueryWrapper();
        ((QueryWrapper) wrapper).like(ESconst.ES_INDEX_NEWS,keyword);

        IPage<FakeNews> listData = fakeNewsMapper.selectPage(pageParam, wrapper);
        return listData;
    }

    @Override
    public void careateIndex() {
        //创建索引请求————————————————————————————————————————————————————
        CreateIndexRequest request=new CreateIndexRequest(ESconst.ES_INDEX_NEWS);
        //创建分片和副本
        request.settings(
                Settings.builder()
                .put("index.number_of_shards", 5)//分片数，默认： 5
                .put("index.number_of_replicas", 1)//副本数，默认： 1
        );

        //客户端执行请求 IndicesClient,请求后获得相应
        try {
            CreateIndexResponse createIndexResponse=restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    @Override
    public void getIndex(){
        GetIndexRequest request=new GetIndexRequest(ESconst.ES_INDEX_NEWS);
        try {
            boolean response=restHighLevelClient.indices().exists(request,RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void deleteIndex(){
        DeleteIndexRequest request= new DeleteIndexRequest(ESconst.ES_INDEX_NEWS);
        try {
            AcknowledgedResponse delete=restHighLevelClient.indices().delete(request,RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void addDocument(){
        //创建对象
        FakeNews fakeNews = new FakeNews();
        //创建请求
        IndexRequest request = new IndexRequest(ESconst.ES_INDEX_NEWS);
        //设置文档规则 PUT/fake_news/_doc/1
        request.id(UUID.randomUUID().toString());
        request.timeout(TimeValue.timeValueSeconds(1));
        request.timeout("1s");
        //创建索引数据
        fakeNews.setNewsTitle("");
        //将请求封装到JSON
        request.source(JSON.toJSONString(fakeNews), XContentType.JSON);

        //客户端发送请求
        try {
            IndexResponse indexResponse = restHighLevelClient.index(request, RequestOptions.DEFAULT);
            System.out.println(indexResponse.toString());
            System.out.println(indexResponse.status());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void getIndexDocument(){
        GetRequest getRequest = new GetRequest(ESconst.ES_INDEX_NEWS,"1");
        //不获取返回的_source 上下文
        getRequest.fetchSourceContext(new FetchSourceContext(false));
        getRequest.storedFields("_none_");

        try {
            //判断文档是否真实存在
            boolean exists=restHighLevelClient.exists(getRequest,RequestOptions.DEFAULT);

            if(exists){
                GetResponse getResponse = restHighLevelClient.get(getRequest, RequestOptions.DEFAULT);

                String respose=getResponse.getSourceAsString();//纯文档数据返回值
                String resposeApi=getResponse.toString();//和API一样的所有返回值
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void updateIndexDocument(){
        UpdateRequest updateRequest = new UpdateRequest(ESconst.ES_INDEX_NEWS,"1");
        //不获取返回的_source 上下文
        updateRequest.timeout("1s");

        FakeNews fakeNews=new FakeNews();
        fakeNews.setNewsTitle("更改信息！");

        updateRequest.doc(JSON.toJSONString(fakeNews), XContentType.JSON);

        try {
            UpdateResponse updateResponse = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    @Override
    public void deleteIndexDocument(){
        DeleteRequest deleteRequest = new DeleteRequest(ESconst.ES_INDEX_NEWS,"1");
        //不获取返回的_source 上下文
        deleteRequest.timeout("1s");

        try {
            DeleteResponse updateResponse = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    @Override
    public void bulkRequest(){
        BulkRequest bulkRequest=new BulkRequest();
        bulkRequest.timeout("1s");
        List<FakeNews> list=new ArrayList<>();
        FakeNews fakeNews = new FakeNews();
        FakeNews fakeNews_1 = new FakeNews();
        fakeNews.setNewsTitle("新闻");
        fakeNews_1.setNewsTitle("新闻1");
        list.add(fakeNews);
        list.add(fakeNews_1);

        for (int i=0;i<=list.size();i++){

            //所有批处理都在这里
            bulkRequest.add(
                    new IndexRequest(ESconst.ES_INDEX_NEWS).id(""+(i+1))
                    .source(JSON.toJSONString(list.get(i)),XContentType.JSON)
            );
        }

        try {
            BulkResponse restResponse = restHighLevelClient.bulk(bulkRequest,RequestOptions.DEFAULT);

            restResponse.hasFailures();//是否失败  返回FALSE 标识成功
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    @Override
    public void searchDoc(){
        SearchRequest searchResult = new SearchRequest(ESconst.ES_INDEX_NEWS);

        //构造搜索条件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //查询条件使用QueryBuilders来构建
        TermQueryBuilder termQueryBuilder=QueryBuilders.termQuery("news_title","海绵宝宝");//精确查询
        MatchAllQueryBuilder matchAllQueryBuilder=QueryBuilders.matchAllQuery();//匹配所有
        searchSourceBuilder.query(termQueryBuilder);
        searchSourceBuilder.query(matchAllQueryBuilder);

        //传入查询条件
        searchResult.source(searchSourceBuilder);

        try {
            SearchResponse searchResponse=restHighLevelClient.search(searchResult,RequestOptions.DEFAULT);

            for(SearchHit docfiles:searchResponse.getHits().getHits()){

                System.out.println(docfiles.getSourceAsMap());
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    @Override
    public FakeNews addData() {
        Date date=new Date();
        FakeNews fakeNews=new FakeNews();
//        fakeNews.setNewsId(UUID.randomUUID().toString());
        fakeNews.setNewsTitle("海绵宝宝玩偶!!");
        fakeNewsMapper.insert(fakeNews);
        return fakeNews;
    }
}
